package gui.GLListeners;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Observable;
import java.util.Properties;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

import textures.TextureReader;
import utils.files.FileManager;
import camaras.Camara;

import componentes.Componente3D;

import constantes.Consts;

public abstract class GLListener extends Observable implements GLEventListener {

	protected double xLeft, xRight, yTop, yBot, xCentro, yCentro;
	
	protected double RatioViewPort;

	protected GLU glu;

	protected GL gl;

	protected Componente3D componente;

	protected Camara camara;

	protected int texture;
	
	protected String texturePath;
	
	protected boolean textureBlended;

	public void display(GLAutoDrawable arg0) {

	}

	public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {

	}

	public void init(GLAutoDrawable arg0) {

	}

	public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
			int arg4) {

	}

	public void keyPressed(KeyEvent arg0) {

	}

	public void keyReleased(KeyEvent arg0) {

	}

	public void keyTyped(KeyEvent arg0) {

	}

	public void mouseEntered(MouseEvent me) {

	}

	public void mouseExited(MouseEvent me) {

	}

	public void mouseClicked(MouseEvent me) {

	}

	public void mousePressed(MouseEvent me, double width, double height) {

	}

	public void mouseReleased(MouseEvent me) {

	}

	public void mouseMoved(MouseEvent me, double width, double height) {

	}

	public void mouseDragged(MouseEvent me, double width, double height) {

	}

	public void mouseWheelMoved(MouseWheelEvent evt) {

	}

	public Componente3D getComponente() {
		return componente;
	}

	public Camara getCamara() {
		return camara;
	}

	public void setCamara(Camara camara) {
		this.camara = camara;
	}

	public void setComponente(Componente3D componente) {
		this.componente = componente;
	}

	public GLU getGlu() {
		return glu;
	}

	public void setGlu(GLU glu) {
		this.glu = glu;
	}

	public GL getGl() {
		return gl;
	}

	public void setGl(GL gl) {
		this.gl = gl;
	}
	
	protected void makeRGBTexture(GL gl, GLU glu, TextureReader.Texture img,
			int target, boolean mipmapped) {

		if (mipmapped) {
			glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img
					.getHeight(), GL.GL_RGB, GL.GL_UNSIGNED_BYTE, img
					.getPixels());
		} else {
			gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img
					.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, img
					.getPixels());
		}
	}
	
	protected int genTexture(GL gl) {
		final int[] tmp = new int[1];
		gl.glGenTextures(1, tmp, 0);
		return tmp[0];
	}
	
	public void setTexture(String path){
		texturePath = path;
		gl.glEnable(GL.GL_TEXTURE_2D);
		texture = genTexture(gl);
		gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
		TextureReader.Texture texture = null;
		try {
			texture = TextureReader.readTexture(path);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		makeRGBTexture(gl, glu, texture, GL.GL_TEXTURE_2D, false);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
				GL.GL_LINEAR);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
				GL.GL_LINEAR);
		setTexture();
	}
	
	protected void setTexture(){
		
	}
	
	public void removeTexture(){
		texturePath = null;
		componente.removeTexture();
	}

	public void save(String path) {
		try {
			FileManager.copyFile(Consts.CONFIG_TEMPLATE,path+".properties");	
			Properties properties = new Properties();
			InputStreamReader input = new InputStreamReader(new FileInputStream(new File(path+".properties")));
			properties.load(input);
			String value = "false";
			if(textureBlended==true){
				value = "true";
			}
			properties.setProperty("texture.blended", value);
			if(texturePath!=null)
				properties.put("texture", texturePath);
			properties.store(new OutputStreamWriter(new FileOutputStream(path+".properties")), "");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void setTextureBlended(boolean blended) {
		textureBlended=blended;
		componente.setTextureBlended(blended);		
	}

	public boolean isTextureBlended() {
		return textureBlended;
	}

}
